package mint.modules.generator.expression;

import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;

import org.antlr.runtime.tree.Tree;

import mint.modules.generator.Scope;
import mint.modules.type.Type;

public class ExclusiveOrExprNode extends Expression {
	private Expression left, right;
	private Type type;
	private int line;
	private List<String> errors;
	private String operator;

	public ExclusiveOrExprNode(Scope theParent, ExpressionType exprType, Tree exclusiveOrTree) {
		super(theParent, exprType);
		
		type = null;
		line = exclusiveOrTree.getLine();
		errors = new ArrayList<String>();
		operator = null;
		
		if (exclusiveOrTree.getText().equals("^"))
		{
			left = new ExclusiveOrExprNode(theParent, exprType, exclusiveOrTree.getChild(0));
			right = new AndExprNode(theParent, exprType, exclusiveOrTree.getChild(1));
			operator = exclusiveOrTree.getText();
		}
		else
		{
			left = new AndExprNode(theParent, exprType, exclusiveOrTree);
			right = null;
		}
	}

	@Override
	public void testSemantic() {
		left.testSemantic();
		type = left.getType();
		
		if (right != null)
		{
			if (getExpressionType() != ExpressionType.Right)
				errors.add(line + ": " + operator + " must be used on the right side of a expression");
			
			right.testSemantic();
			type = Type.intType;
			
			Type typeLeft = left.getType();
			Type typeRight = right.getType();			
			
			if (typeLeft.equals(Type.intType))
			{
				if (!typeRight.equals(Type.intType))									
					errors.add(line + ": " + operator + " must be used on integer expressions");				
			} else
				errors.add(line + ": " + operator + " must be used on integer expressions");						
		}
	}

	@Override
	public List<String> getSemanticErrors() {
		errors.addAll(left.getSemanticErrors());
		if (right != null)
			errors.addAll(right.getSemanticErrors());
		return errors;
	}

	@Override
	public void emit(Formatter output) {
		left.emit(output);
		
		if (operator != null)
		{
			right.emit(output);
			output.format("ixor\n");
		}
	}

	@Override
	public int getLine() {
		return line;
	}

	@Override
	public Type getType() {		
		return type;
	}

	@Override
	public void leftEmit(Formatter output) {
		left.leftEmit(output);		
	}

}
